﻿using ParkLBS.FrameWork;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;

namespace ParkLBS.Controller
{
    public partial class parklbs1 : System.Web.UI.Page
    {
        const string Token = "mxmchina";//你的token  http://101.251.199.202/View/default.html
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.HttpMethod.ToLower() == "post")
            {

                #region
                try
                {
                    wxmessage wx = GetWxMessage();
                    string res = "";

                    if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "CLICK")
                    {
                        if (wx.EventKey == "PARKLIST")
                        {
                            try
                            {
                                UserLOCATION location = new UserLOCATION();
                                location = GetUserLocationByOpenID(wx.FromUserName);

                                if (location != null)
                                {
                                    ParkList list = new ParkList();
                                    list = GetNearParks(location.Latitude, location.Longitude);
                                    wx.Latitude = location.Latitude;
                                    wx.Longitude = location.Longitude;
                                    res = ReplyPicMessage(list, wx);
                                    Response.Write(res);
                                }
                                else {
                                    res = sendTextMessage(wx, "无法获取您的地理位置，请手动发送地理位置");
                                    WriteLog(res);
                                    Response.Write(res);
                                }
                            }
                            catch (Exception ex)
                            {

                                WriteLog(ex.ToString());
                            }
                        }
                        else if (wx.EventKey == "PARKMAP")
                        {
                            try
                            {
                                UserLOCATION location = new UserLOCATION();
                                location = GetUserLocationByOpenID(wx.FromUserName);

                                if (location != null)
                                {
                                    wx.Latitude = location.Latitude;
                                    wx.Longitude = location.Longitude;
                                }
                                else {
                                    wx.Latitude = string.Empty;
                                    wx.Longitude = string.Empty;
                                }
                                
                                    res = ReplyParkMap(wx);
                                    //WriteLog(res);
                                    Response.Write(res);
            
                            }
                            catch (Exception ex)
                            {
                                WriteLog(ex.ToString());
                            }
                        }
                    }
                    else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "LOCATION")
                    {
                        WriteLog("您的位置是经度：" + wx.Latitude + "，维度是：" + wx.Longitude + "，地理经度为：" + wx.Precision);
                        //res = sendTextMessage(wx, "您的位置是经度：" + wx.Latitude + "，维度是：" + wx.Longitude + "，地理经度为：" + wx.Precision);
                    }
                    else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "subscribe")
                    {
                        //发送欢迎信息
                        res = ReplyWelcome(wx);
                        
                        Response.Write(res);
                    }
                    else
                    {
                        if (wx.MsgType == "text" && wx.Content == "你好")
                        {
                            WriteLog("你好,欢迎使用北京公联安达科技有限公司公共微信平台!");
                            //res = sendTextMessage(wx, "你好,欢迎使用北京永杰友信科技有限公司公共微信平台!");
                        }
                        else if (wx.MsgType == "location")
                        {
                            //WriteLog("您发送的位置是:" + wx.Label + ";纬度是:" + wx.Location_X + ";经度是:" + wx.Location_Y + ";缩放比例为:" + wx.Scale);

                            //ParkList list = new ParkList();
                            //list = GetNearParks(wx.Location_X, wx.Location_Y);
                            //wx.Longitude = wx.Location_Y;
                            //wx.Latitude = wx.Location_X;
                            //res = ReplyPicMessage(list, wx);
                            //Response.Write(res);
                        }
                        else
                        {
                            WriteLog("你好,未能识别消息!");
                            //res = sendTextMessage(wx, "你好,未能识别消息!");
                        }
                    }

                    //Response.Write(res);
                }
                catch (Exception es)
                {
                    WriteLog(es.ToString());
                }

                #endregion
            }
            else//微信服务器将发送GET请求到填写的URL上
            {
                WriteLog("get请求进入");
                Valid();
            }
            
        }
        private string sendTextMessage(wxmessage wx, string content)
        {
            string res = string.Format(@"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml> ",
                wx.FromUserName, wx.ToUserName, DateTime.Now, content);
            return res;
        } 

        private string sendClickMessage(wxmessage wx, string url)
        {
            string res = string.Format(@"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[{3}]]></EventKey>
</xml>",
                wx.FromUserName, wx.ToUserName, DateTime.Now, url);
            return res;
        }  

        #region 验证url有效性
        /// <summary>
        /// 验证微信签名
        /// </summary>
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// <returns></returns>
        private bool CheckSignature()
        {
            string signature = Request.QueryString["signature"].ToString();
            string timestamp = Request.QueryString["timestamp"].ToString();
            string nonce = Request.QueryString["nonce"].ToString();
            string[] ArrTmp = { Token, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void Valid()
        {
            string echoStr = Request.QueryString["echoStr"].ToString();

            


            if (CheckSignature())
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    Response.Write(echoStr);
                    Response.End();
                }
            }
        }
        #endregion

        #region 获取ACCESSTOKEN 7200秒 两个小时有效 string _access_token = IsExistAccess_Token();

        public Access_token GetAccess_token()
        {
            Access_token mode = new Access_token();
            try
            {
                string appid = "wx94d4bdadf15bebcf";
                string secret = "cbba37ed2e35b163408165959db24660";
                string strUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;

                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(strUrl);

                req.Method = "GET";
                using (WebResponse wr = req.GetResponse())
                {
                    HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();

                    StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);

                    string content = reader.ReadToEnd();
                    //Response.Write(content);
                    //在这里对Access_token 赋值
                    Access_token token = new Access_token();
                    token = JsonHelper.JsonDeserialize<Access_token>(content);
                    mode.access_token = token.access_token;
                    mode.expires_in = token.expires_in;
                }
                
            }
            catch (Exception ex)
            {

                WriteLog("获取凭证报错：" + ex.ToString());
            }
            return mode;
            
        }

        /// <summary>
        /// 根据当前日期 判断Access_Token 是否超期  如果超期返回新的Access_Token   否则返回之前的Access_Token
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public string IsExistAccess_Token()
        {
            string Token = string.Empty;
            DateTime YouXRQ;
            // 读取XML文件中的数据，并显示出来 ，注意文件路径
            string filepath = Server.MapPath("/Files/XMLFile.xml");

            StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);
            XmlDocument xml = new XmlDocument();
            xml.Load(str);
            str.Close();
            str.Dispose();
            Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText;
            YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText);

            if (DateTime.Now > YouXRQ)
            {
                DateTime _youxrq = DateTime.Now;
                Access_token mode = GetAccess_token();
                xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.access_token;
                _youxrq = _youxrq.AddSeconds(int.Parse(mode.expires_in));
                xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString();
                xml.Save(filepath);
                Token = mode.access_token;
            }
            return Token;
        }

        #endregion

        #region 获取用户信息

        private wxmessage GetWxMessage()
        {
            wxmessage wx = new wxmessage();
            StreamReader str = new StreamReader(Request.InputStream, System.Text.Encoding.UTF8);
            XmlDocument xml = new XmlDocument();
            xml.Load(str);
            wx.ToUserName = xml.SelectSingleNode("xml").SelectSingleNode("ToUserName").InnerText;
            wx.FromUserName = xml.SelectSingleNode("xml").SelectSingleNode("FromUserName").InnerText;
            wx.MsgType = xml.SelectSingleNode("xml").SelectSingleNode("MsgType").InnerText;
            WriteLog("MsgType:" + wx.MsgType + "   ToUserName：" + wx.ToUserName + "    FromUserName:" + wx.FromUserName);
            if (wx.MsgType.Trim() == "event")
            {
                WriteLog("event方法请求");
                wx.EventName = xml.SelectSingleNode("xml").SelectSingleNode("Event").InnerText;
                WriteLog("event方法名称：" + wx.EventName);
                if (wx.EventName.ToUpper() == "LOCATION")
                {
                    wx.Latitude = xml.SelectSingleNode("xml").SelectSingleNode("Latitude").InnerText;
                    wx.Longitude = xml.SelectSingleNode("xml").SelectSingleNode("Longitude").InnerText;
                    wx.Precision = xml.SelectSingleNode("xml").SelectSingleNode("Precision").InnerText;

                    ModifyUserLocation(wx);

                }
                else if (wx.EventName.ToUpper() == "CLICK")
                {
                    wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey").InnerText;
                }
                else
                {
                    wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey").InnerText;
                }
            }
            if (wx.MsgType.Trim() == "text")
            {
                wx.Content = xml.SelectSingleNode("xml").SelectSingleNode("Content").InnerText;
            }
            if (wx.MsgType.Trim() == "location")
            {
                wx.Location_X = xml.SelectSingleNode("xml").SelectSingleNode("Location_X").InnerText;
                wx.Location_Y = xml.SelectSingleNode("xml").SelectSingleNode("Location_Y").InnerText;
                wx.Scale = xml.SelectSingleNode("xml").SelectSingleNode("Scale").InnerText;
                wx.Label = xml.SelectSingleNode("xml").SelectSingleNode("Label").InnerText;
                
            }

            return wx;
        }

        #endregion

        #region Writelog

        /// <summary>
        /// 写日志(用于跟踪)
        /// </summary>
        private void WriteLog(string strMemo)
        {
            clsLogHelper.WriteLog(null,null,strMemo);
        }

        #endregion

        #region Location信息

        /// <summary>
        /// 根据用户ID获取用户地理位置信息
        /// </summary>
        /// <param name="openid"></param>
        /// <returns></returns>
        public UserLOCATION GetUserLocationByOpenID(string openid)
        {
            UserLOCATION location = new UserLOCATION();
            string FilePath = System.IO.Path.Combine(HttpRuntime.AppDomainAppPath, @"Files\UserLocations.xml");
            WebSiteDB.LoadDbFromXml(FilePath);
            location = WebSiteDB.MyNorthwind.UserLOCATIONs.FirstOrDefault(p => p.UserID == openid);

            if (location != null)
                return location;
            else
                return null;

        }

        /// <summary>
        /// 更新用户Location信息
        /// </summary>
        /// <param name="wx"></param>
        public void ModifyUserLocation(wxmessage wx)
        {
            string FilePath = System.IO.Path.Combine(HttpRuntime.AppDomainAppPath, @"Files\UserLocations.xml");
            try
            {
                WebSiteDB.LoadDbFromXml(FilePath);

                UserLOCATION location = new UserLOCATION();
                location = WebSiteDB.MyNorthwind.UserLOCATIONs.FirstOrDefault(p => p.UserID == wx.FromUserName);

                bool IsCunzai = false;
                if (location != null)
                    IsCunzai = true;
                else
                    location = new UserLOCATION();

                location.UserID = wx.FromUserName;
                location.Latitude = wx.Latitude;
                location.Longitude = wx.Longitude;
                location.Precision = wx.Precision;
                location.DataDate = DateTime.Now;

                WriteLog(FilePath);
                if (!IsCunzai)
                    WebSiteDB.MyNorthwind.UserLOCATIONs.Add(location);
                WebSiteDB.SaveDbToXml(FilePath);
            }
            catch (Exception ex)
            {
                WriteLog("更新UserLocation信息出错" + ex.ToString());
            }
        }

        /// <summary>
        /// 根据经纬度获取附近停车场列表
        /// </summary>
        /// <param name="lon"></param>
        /// <param name="lat"></param>
        public ParkList GetNearParks(string lon, string lat)
        {
            WriteLog("lon：" + lon + "  lat:" + lat);
            string url = @"http://yuntuapi.amap.com/datasearch/around?tableid=53e8b75ce4b08f92c0ffa6f2&radius=50000&center=" + lat + "," + lon + "&&limit=5&page=1&key=1c69b4a7bc3ff8773bcb6fa31605bb1c";
            string str = HttpUtility.GetData(url);
            ParkList list = new ParkList();
            try
            {
                list = JsonHelper.JsonDeserialize<ParkList>(str);
            }
            catch (Exception ex)
            {
                WriteLog(ex.ToString());
            }

            return list;
        }

        /// <summary>
        /// 回复图片消息（停车场信息）
        /// </summary>
        /// <param name="list"></param>
        /// <param name="wx"></param>
        /// <returns></returns>
        public string ReplyPicMessage(ParkList list,wxmessage wx)
        {
            XElement ex = new XElement("xml",
                new XElement("ToUserName", "<![CDATA[" + wx.FromUserName + "]]>"),
                new XElement("FromUserName", "<![CDATA["+wx.ToUserName+"]]>"),
                new XElement("CreateTime", DateTime.Now),
                new XElement("MsgType", "<![CDATA[news]]>"),
                new XElement("ArticleCount",6));

            XElement Articles = new XElement("Articles");

            list.datas.ForEach(p => {

                var lon = p._location.Split(',')[0];
                var lat = p._location.Split(',')[1];
                string mapUrl = "http://mo.amap.com/?q=" + lat + "," + lon + "&name=" + Server.UrlEncode(p._name) + "&dev=0";

                XElement item = new XElement("item",
                   new XElement("Title", "<![CDATA["+p._name+"]]>"),
                   new XElement("Description", "<![CDATA["+p._address+"]]>"),
                   new XElement("PicUrl", "http://101.251.199.202/images/1394502727.jpg"),
                   new XElement("Url", "<![CDATA[" + mapUrl + "]]>"));
                
                Articles.Add(item);
            });

            string url = "http://101.251.199.202/View/parkList.html?_location=" + wx.Longitude + "," + wx.Latitude;
            XElement lastitem = new XElement("item",
                   new XElement("Title", "<![CDATA[查看列表]]>"),
                   new XElement("Description", "<![CDATA[共" + list.count + "条信息]]>"),
                   new XElement("PicUrl", ""),
                   new XElement("Url", "<![CDATA[" + url + "]]>"));
            Articles.Add(lastitem);
            ex.Add(Articles);

            return ex.ToString().Replace("&lt;", "<").Replace("&gt;", ">");
           
        }

        public string ReplyParkMap(wxmessage wx)
        {
            XElement ex = new XElement("xml",
                           new XElement("ToUserName", "<![CDATA[" + wx.FromUserName + "]]>"),
                           new XElement("FromUserName", "<![CDATA[" + wx.ToUserName + "]]>"),
                           new XElement("CreateTime", DateTime.Now),
                           new XElement("MsgType", "<![CDATA[news]]>"),
                           new XElement("ArticleCount", 1));

            XElement Articles = new XElement("Articles");

            string url = string.Empty;
            if (!string.IsNullOrEmpty(wx.Longitude))
                url = "http://101.251.199.202/View/parkmap.html?_location=" + wx.Longitude + "," + wx.Latitude;
            else
                url = "http://101.251.199.202/View/parkmap.html?_location=";
            XElement lastitem = new XElement("item",
                   new XElement("Title", "<![CDATA[停车场分布图]]>"),
                   new XElement("Description", "<![CDATA[点击查看]]>"),
                   new XElement("PicUrl", "http://101.251.199.202/images/dt.png"),
                   new XElement("Url", "<![CDATA[" + url + "]]>"));
            Articles.Add(lastitem);
            ex.Add(Articles);

            return ex.ToString().Replace("&lt;", "<").Replace("&gt;", ">");
        }

        public string ReplyWelcome(wxmessage wx)
        {
            XElement ex = new XElement("xml",
                                      new XElement("ToUserName", "<![CDATA[" + wx.FromUserName + "]]>"),
                                      new XElement("FromUserName", "<![CDATA[" + wx.ToUserName + "]]>"),
                                      new XElement("CreateTime", DateTime.Now),
                                      new XElement("MsgType", "<![CDATA[news]]>"),
                                      new XElement("ArticleCount", 4));

            XElement Articles = new XElement("Articles");
            XElement lastitem1 = new XElement("item",
                   new XElement("Title", "<![CDATA[北京公联安达停车管理有限公司]]>"),
                   new XElement("Description", "<![CDATA[北京公联安达停车管理有限公司]]>"),
                   new XElement("PicUrl", "http://101.251.199.202/images/logos.png"),
                   new XElement("Url", "<![CDATA[http://www.gladpark.com/]]>"));

            string weather = GetWeather();
            XElement lastitem2 = new XElement("item",
                   new XElement("Title", "<![CDATA[" + weather + "]]>"),
                   new XElement("Description", ""),
                   new XElement("PicUrl", "http://101.251.199.202/images/weathers.png"),
                   new XElement("Url", ""));

            XElement lastitem3 = new XElement("item",
                   new XElement("Title", "<![CDATA[关于北京公联安达微信平台使用说明]]>"),
                   new XElement("Description", ""),
                   new XElement("PicUrl", "http://101.251.199.202/images/helps.png"),
                   new XElement("Url", "<![CDATA[http://101.251.199.205/bjysj/help.htm]]>"));

            XElement lastitem4 = new XElement("item",
                  new XElement("Title", "<![CDATA[你好,欢迎关注北京公联安达停车管理有限公司]]>"),
                  new XElement("Description", ""),
                  new XElement("PicUrl", "http://101.251.199.202/images/logo_m.png"),
                  new XElement("Url", "<![CDATA[http://www.gladpark.com/]]>"));
            Articles.Add(lastitem1);
            Articles.Add(lastitem2);
            Articles.Add(lastitem3);
            Articles.Add(lastitem4);
            ex.Add(Articles);

            return ex.ToString().Replace("&lt;", "<").Replace("&gt;", ">");

        }

        public string GetWeather()
        {
            string result = string.Empty;
            try
            {
                string url = "http://weatherapi.market.xiaomi.com/wtr-v2/temp/realtime?cityId=101010100";
                string str = HttpUtility.GetData(url);
                int s1 = str.IndexOf("{", 2);
                int s2 = str.LastIndexOf("}");

                string ss = str.Substring(s1, s2 - s1);
                XiaomiWeather info = new XiaomiWeather();
                info = JsonHelper.JsonDeserialize<XiaomiWeather>(ss);

                result = DateTime.Now.ToShortDateString() + "\n北京  " + info.weather + "  " + info.temp + "℃  " + info.WD + "  " + info.WS; 
            }
            catch (Exception ex)
            {
                WriteLog(ex.ToString());
            }

            return result;
        }


        #endregion

        #region 发送请求

        public string SendMessage(string content)
        {
            string _access_token = IsExistAccess_Token();

            WriteLog("获取到的凭证：" + _access_token);
            string url = string.Format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}", _access_token);
            //string menu = FileUtility.Read(Menu_Data_Path);
            try
            {
                return HttpUtility.SendHttpRequest(url, content);
            }
            catch (Exception ex)
            {
                WriteLog("提交请求打开页面报错"+ex.ToString());
            }

            return string.Empty;
            
        }
        #endregion
    }
}